﻿#region using
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Schema;

using XmlGenSharp.Logic.Main.Configuration;
#endregion

namespace XmlGenSharp.Logic.Main
{
  public class MultiOutputAnalyzerContext : AnalyzerContext
  {
    // Constructors

    #region MultiOutputAnalyzerContext(BindingAnalyzer bindingAnalyzer)
    public MultiOutputAnalyzerContext(BindingAnalyzer bindingAnalyzer) : base(bindingAnalyzer)
    {
      ((TextFileGenerator)PrimaryGenerator).Content = "Generator status messages";
    }
    #endregion

    // Public Properties

    #region PrimaryGenerator
    public IGenerator PrimaryGenerator
    {
      get
      {
        if (_primaryGenerator == null)
          _primaryGenerator = new TextFileGenerator(BindingAnalyzer.InputFileName, BindingAnalyzer.DefaultNamespace);

        return _primaryGenerator;
      }
    }
    private IGenerator _primaryGenerator = null;
    #endregion

    #region SecondaryGenerators
    public IList<IGenerator> SecondaryGenerators
    {
      get
      {
        if (_secondaryGenerators == null)
          _secondaryGenerators = new List<IGenerator>();

        return _secondaryGenerators;
      }
    }
    private IList<IGenerator> _secondaryGenerators;
    #endregion

    // Public Methods

    #region FoundComplexType(XmlSchemaComplexType complexType)
    public override void FoundComplexType(XmlSchemaComplexType complexType)
    {
      if (BindingAnalyzer != null && BindingAnalyzer.Config != null && BindingAnalyzer.Config.ClassTable != null)
      {
        ClassConfigData ccd = BindingAnalyzer.Config.ClassTable.FindClass(complexType.Name);
        if (ccd != null && !ccd.Generate)
        {
          // The user has requested that this class not be generated.  Presumably,
          // the class comes from someplace else, either a hand-coded class, or
          // perhaps a class that was generated separately by XmlGen# from another XSD file.

          return;
        }
      }

      ClassGenerator cg = new ClassGenerator(BindingAnalyzer.InputFileName, BindingAnalyzer.DefaultNamespace, complexType);

      StringBuilder sb = new StringBuilder();
      StringWriter sw = new StringWriter(sb);

      AppendXsdInfo(sw);
      AppendCommonPreText(sw, BindingAnalyzer.DefaultNamespace);

      cg.PreText = sb.ToString();
      cg.PostText = "}";

      SecondaryGenerators.Add(cg);
      SecondaryGenerators.Add(new CustomChangesGenerator(BindingAnalyzer.InputFileName, BindingAnalyzer.DefaultNamespace, complexType.Name));
    }
    #endregion

    #region FoundSimpleType(XmlSchemaSimpleType simpleType)
    public override void FoundSimpleType(XmlSchemaSimpleType simpleType)
    {
      EnumGenerator eg = new EnumGenerator(BindingAnalyzer.InputFileName, BindingAnalyzer.DefaultNamespace, simpleType);

      StringBuilder sb = new StringBuilder();
      StringWriter sw = new StringWriter(sb);

      AppendXsdInfo(sw);
      AppendCommonPreText(sw, BindingAnalyzer.DefaultNamespace);

      eg.PreText = sb.ToString();
      eg.PostText = "}";

      SecondaryGenerators.Add(eg);
      SecondaryGenerators.Add(new CustomChangesGenerator(BindingAnalyzer.InputFileName, BindingAnalyzer.DefaultNamespace, simpleType.Name));
    }
    #endregion

    #region FoundEnumeration(EnumerationInfo enumerationInfo)
    public override void FoundEnumeration(EnumerationInfo enumerationInfo)
    {
      AdvancedEnumGenerator aeg = new AdvancedEnumGenerator(BindingAnalyzer.InputFileName, BindingAnalyzer.DefaultNamespace, enumerationInfo);

      StringBuilder sb = new StringBuilder();
      StringWriter sw = new StringWriter(sb);

      AppendCommonPreText(sw, BindingAnalyzer.DefaultNamespace);

      aeg.PreText = sb.ToString();
      aeg.PostText = "}";

      _primaryGenerator = aeg;
      SecondaryGenerators.Add(new CustomChangesGenerator(BindingAnalyzer.InputFileName, BindingAnalyzer.DefaultNamespace, string.Empty, enumerationInfo.Name));
    }
    #endregion

    #region FoundEnumerationElement(EnumerationInfo enumerationInfo, Element element)
    public override void FoundEnumerationElement(EnumerationInfo enumerationInfo, Element element)
    {
      SecondaryGenerators.Add(
        new SubclassCustomChangesGenerator(
          BindingAnalyzer.InputFileName, 
          BindingAnalyzer.DefaultNamespace, 
          element.Name,
          enumerationInfo.Name,
          element.Name + enumerationInfo.Name));
    }
    #endregion
  }
}
